﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Xml.Linq;

namespace PersonalAlbum
{
    public class XmlMembershipProvider : System.Web.Security.MembershipProvider
    {
       
        public override string ApplicationName { get; set; }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            var usersFile = new UsersData();
            var user = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == username && u.Element("Password").Value.Trim() == oldPassword select u).SingleOrDefault();
            if (user != null)
            {
                user.Element("Password").ReplaceWith(new XElement("Password", newPassword));
                usersFile.Save();
                return true;
            }
            else
            {
                return false;
            }
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            return false;
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            var usersFile = new UsersData();

            status = MembershipCreateStatus.Success;
            usersFile.Element("Users").Add(new XElement("User", new XElement("Name", username),
                new XElement("Email", email),
                new XElement("Password", password),
                new XElement("Approved",isApproved)));
            usersFile.Save();
            return Load(username);
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            var usersFile = new UsersData();

            var user = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == username select u).SingleOrDefault();
            if (user != null)
            {
                user.Remove();
                usersFile.Save();
                return true;
            }
            else
            {
                return false;
            }
        }

        public override bool EnablePasswordReset
        {
            get { return false; }
        }

        public override bool EnablePasswordRetrieval
        {
            get { return true; }
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            var usersFile = new UsersData();

            var users = (from u in usersFile.Descendants("User") where u.Element("Email").Value.Trim() == emailToMatch select u);
            MembershipUserCollection m = new MembershipUserCollection();
            foreach (var user in users)
            {
                m.Add(new MembershipUser("XmlMemberShipProvider", user.Element("Name").Value, null, user.Element("Email").Value, null, null, true, false, DateTime.Now.AddDays(-7), DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-7), DateTime.MinValue));
            }
            totalRecords = users.Count();
            return m;
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            var usersFile = new UsersData();

            var users = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == usernameToMatch select u);
            MembershipUserCollection m = new MembershipUserCollection();
            foreach (var user in users)
            {
                m.Add(new MembershipUser("XmlMemberShipProvider", user.Element("Name").Value, null, user.Element("Email").Value, null, null, true, false, DateTime.Now.AddDays(-7), DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-7), DateTime.MinValue));
            }
            totalRecords = users.Count();
            return m;
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            var usersFile = new UsersData();

            var users = (from u in usersFile.Descendants("User") select u);
            MembershipUserCollection m = new MembershipUserCollection();
            foreach (var user in users)
            {
                m.Add(new MembershipUser("XmlMemberShipProvider", user.Element("Name").Value, null, user.Element("Email").Value, null, null, true, false, DateTime.Now.AddDays(-7), DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-1), DateTime.Now.AddDays(-7), DateTime.MinValue));
            }
            totalRecords = users.Count();
            return m;
        }

        public override int GetNumberOfUsersOnline()
        {
            return 1;
        }

        public override string GetPassword(string username, string answer)
        {
            var usersFile = new UsersData();

            var user = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == username select u).SingleOrDefault();
            if (user != null)
            {
                return user.Element("Password").Value;
            }
            throw new Exception("No user was found with the name " + username);
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {

            return Load(username);

        }

        private MembershipUser Load(string username)
        {
            var usersFile = new UsersData();

            var user = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == username select u).SingleOrDefault();
            if (user != null)
            {
                return new MembershipUser("XmlMemberShipProvider",
                    user.Element("Name").Value,//user name
                    null,
                    user.Element("Email").Value,//email
                    null,
                    null,
                    (bool)user.Element("Approved"),//is approved
                    false,//is locked out
                    DateTime.Now.AddDays(-7),//creation date
                    DateTime.Now.AddDays(-1), //last login date
                    DateTime.Now.AddDays(-1),//last activity date
                    DateTime.Now.AddDays(-7),
                    DateTime.MinValue);
            }
            else
            {
                return null;
            }

        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            return Load(null);
        }

        public override string GetUserNameByEmail(string email)
        {
            var usersFile = new UsersData();

            var user = (from u in usersFile.Descendants("User") where u.Element("Email").Value.Trim() == email select u).SingleOrDefault();
            if (user != null)
            {
                return user.Element("Name").Value;
            }
            else
            {
                return null;
            }
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { return 10; }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return 0; }
        }

        public override int MinRequiredPasswordLength
        {
            get { return 1; }
        }

        public override int PasswordAttemptWindow
        {
            get { return 1; }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { return MembershipPasswordFormat.Clear; }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { return @"\w+"; }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { return true; }
        }

        public override bool RequiresUniqueEmail
        {
            get { return true; }
        }

        public override string ResetPassword(string username, string answer)
        {
            var usersFile = new UsersData();

            var user = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == username select u).SingleOrDefault();
            string password = Guid.NewGuid().ToString("N").Substring(0, 8);
            if (user != null)
            {
                user.Element("Password").ReplaceWith(new XElement("Passowrd", password));
            }
            usersFile.Save();

            return password;
        }

        public override bool UnlockUser(string userName)
        {
            return true;
        }

        public override void UpdateUser(MembershipUser user)
        {
            var usersFile = new UsersData();

            var loaded = (from u in usersFile.Descendants("User") where u.Element("Name").Value.Trim() == user.UserName select u).SingleOrDefault();
            if (loaded != null)
            {
                loaded.Element("Email").ReplaceWith(new XElement("Email", user.Email));
                loaded.Element("Approved").ReplaceWith(new XElement("Approved", user.IsApproved));
            }
            usersFile.Save();
        }

        public override bool ValidateUser(string username, string password)
        {
            var usersFile = new UsersData();

            var user = (from u in usersFile.Descendants("User")
                        where
                            u.Element("Name").Value.Trim() == username &&
                            u.Element("Password").Value.Trim() == password &&
                            (bool)u.Element("Approved")
                        select u).SingleOrDefault();
            return user != null;
        }
    }
}
